package com.haulmont.asu.web.ui.gantt;

import com.haulmont.asu.entity.*;
import com.haulmont.asu.web.ui.project.ProjectEditor;
import com.haulmont.cuba.core.global.AppBeans;
import com.haulmont.cuba.core.global.Messages;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.data.category.IntervalCategoryDataset;
import org.jfree.data.gantt.Task;
import org.jfree.data.gantt.TaskSeries;
import org.jfree.data.gantt.TaskSeriesCollection;
import org.jfree.data.time.SimpleTimePeriod;
import org.jfree.ui.ApplicationFrame;

import java.awt.event.WindowEvent;
import java.util.ArrayList;
import java.util.List;

/**
 * Author: Sergey42
 * Date: 22.12.13 18:42
 */
public class GanttDiagram extends ApplicationFrame {

    private static final long serialVersionUID = -576678210054630540L;

    protected String projectName;
    protected int mode;

    protected Project project;

    public GanttDiagram(int mode, String title, String projectName, Project project) {
        super(title);
        this.mode = mode;
        this.project = project;
        this.projectName = projectName;

        final IntervalCategoryDataset dataset = createDataset();
        final JFreeChart chart = createChart(dataset);

        // add the chart to a panel...
        final ChartPanel chartPanel = new ChartPanel(chart);
        chartPanel.setPreferredSize(new java.awt.Dimension(500, 270));
        setContentPane(chartPanel);
    }

    public IntervalCategoryDataset createDataset() {

        final TaskSeries planSeries = new TaskSeries(getMessage("plan"));
        final TaskSeries factSeries = new TaskSeries(getMessage("fact"));

        for (Item work : getItems()) {

            if (work.planFinish() != null && work.planStart() != null) {
                planSeries.add(new Task(work.getName(),
                        new SimpleTimePeriod(work.planStart(), work.planFinish())));
            }

            if (work.factFinish() != null && work.factStart() != null) {
                factSeries.add(new Task(work.getName(),
                        new SimpleTimePeriod(work.factStart(), work.factFinish())));
            }
        }


        final TaskSeriesCollection collection = new TaskSeriesCollection();
        collection.add(planSeries);
        collection.add(factSeries);

        return collection;
    }

    private JFreeChart createChart(final IntervalCategoryDataset dataset) {
        return ChartFactory.createGanttChart(
                formatMessage("title", projectName),  // chart title
                getMessage("tasks"),              // domain axis label
                getMessage("time"),              // range axis label
                dataset,             // data
                true,                // include legend
                true,                // tooltips
                false                // urls
        );
    }

    @Override
    public void windowClosing(final WindowEvent event) {
        if (event.getWindow() == this) {
            dispose();
        }
    }

    public String getMessage(String key) {
        return AppBeans.get(Messages.class).getMessage(GanttDiagram.class, key);
    }

    public String formatMessage(String key, Object... params) {
        return AppBeans.get(Messages.class).formatMessage(GanttDiagram.class, key, params);
    }

    protected List<Item> getItems() {
        List<Item> items = new ArrayList<>();

        if (mode == ProjectEditor.work) {
            for (final Work work : project.getWorks()) {
                items.add(new WorkAdapter(work));
            }
        } else if (mode == ProjectEditor.step) {
            for (final Step step : project.getSteps()) {
                items.add(new StepAdapter(step));
            }
        } else if (mode == ProjectEditor.stage) {
            for (final Stage stage : project.getStages()) {
                items.add(new StageAdapter(stage));
            }
        } else if (mode == ProjectEditor.phase) {
            for (Phase phase : project.getPhases()) {
                items.add(new PhaseAdapter(phase));
            }
        }

        return items;
    }

}
